import { tween, v3, Vec2, Vec3, Node, math } from "cc";

/**
 * 贝塞尔曲线工具类
 */
export class BezierCurve {

    static bezierMove(n: Node, vs: Vec3[]) {
        let p1 = vs[0];
        tween(n).to(3, { position: vs[2] }, {
            onUpdate: (target, ratio) => {
                let temp = this.bezierCurve(ratio, vs[0].clone(), vs[1].clone(), vs[2].clone());//, vs[3]
                // let angle = this.getAngle(p1, temp);
                // console.log(angle)
                // p1 = temp;

                let tangent = this.tangentAt(ratio, vs[0].clone(), vs[1].clone(), vs[2].clone());
                let angle = Math.atan2(tangent.y, tangent.x) * (180 / Math.PI);
                console.log(tangent.y, tangent.x)
                console.log(angle)

                n.angle = angle;
                n.setPosition(temp);

            }
        }).start();
    }

    static bezierCurve(t: number, p1: Vec3, cp: Vec3, p2: Vec3): Vec3 {
        let x = (1 - t) * (1 - t) * p1.x + 2 * t * (1 - t) * cp.x + t * t * p2.x;
        let y = (1 - t) * (1 - t) * p1.y + 2 * t * (1 - t) * cp.y + t * t * p2.y;
        return v3(x, y, 0);
    };

    static bezierCurve3(t: number, p1: Vec3, cp1: Vec3, cp2: Vec3, p2: Vec3): Vec3 {
        let x =
            (1 - t) * (1 - t) * (1 - t) * p1.x +
            3 * t * (1 - t) * (1 - t) * cp1.x +
            3 * t * t * (1 - t) * cp2.x +
            t * t * t * p2.x;
        let y =
            (1 - t) * (1 - t) * (1 - t) * p1.y +
            3 * t * (1 - t) * (1 - t) * cp1.y +
            3 * t * t * (1 - t) * cp2.y +
            t * t * t * p2.y;
        return v3(x, y, 0);
    };

    /** 好像不适合 */
    static getAngle2(p1: Vec3, p2: Vec3) {

        // let oa = Math.sqrt(p1.x * p1.x + p1.y * p1.y);
        // let ob = Math.sqrt(p2.x * p2.x + p2.y * p2.y);
        // let xj = p1.x * p2.y - p1.y * p2.x;//叉积 x1 * y2 - x2 * y1
        // let dj = p1.x * p2.x + p1.y * p2.y;//点积 x1 * x2 + y1 * y2
        // let cos = dj / (oa * ob);//cos
        // let num = Math.acos(cos);//反余弦
        // let angle = num * (180 / Math.PI);
        // if(xj < 0)angle = 180 - angle;

        let theta_oa = math.toDegree(Math.atan2(p1.y, p1.x));
        let theta_ob = math.toDegree(Math.atan2(p2.y, p2.x));
        let delta_theta = theta_ob - theta_oa;
        let angle = delta_theta;

        return angle;
    }

    /** 计算角度(传入向量) */
    getAngle(x1: Vec3, x2: Vec3) {
        //计算模长
        const amo = Math.sqrt((x1.x * x1.x) + (x1.y * x1.y));
        const bmo = Math.sqrt(x2.x * x2.x + x2.y * x2.y);
        //计算点积
        const abdot = x1.x * x2.x + x1.y * x2.y
        //计算余弦值
        const cossin = abdot/(amo * bmo)
        //弧度转角度toDegree(反余弦acos)
        let angle = math.toDegree(Math.acos(cossin))

        //计算叉积(判断正负)
        const cross = x1.x * x2.y + x1.y * x2.x
        if(cross > 0)angle *= -1;//ps：应该是小于0才为负数，测试 >0 才是正常的

        return angle;
    }

    // 求切线方向，即在t处的导数
    static tangentAt(t:number, P0:Vec3, P1:Vec3, P2:Vec3) {
        let v = (P1.subtract(P0)).multiplyScalar(2 * (1 - t)).add( (P2.subtract(P1)).multiplyScalar(2 * t));
        return v.normalize(); // 归一化以得到单位向量
    }

    // static getPositionFirstOrder(p1: Vec3 , p2:Vec3, t: number) {
    //     let val = { x: (1 - t) * p1.x + t * p2.x, y: (1 - t) * p1.y + t * p2.y };
    //     const angle = Math.atan2(val.y - val.y, p123.x - p012.x);
    //     return val;
    // }
}